#!/bin/bash

# Run this script when dev_msgs.h or fabric_telemetry_msgs.h changes.

set -o errexit
set -o nounset

SRC_ROOT="$1"
OUT_DIR="$2"

PYTHON=python3
SCRIPT="$(realpath --relative-to "$SRC_ROOT" "${BASH_SOURCE[0]}")"
SCRIPT_PY="$(dirname ${BASH_SOURCE[0]})/codegen.py"
YEAR=$(date +%Y)

declare -a SRC_FILES=(
    "tt_metal/hw/inc/dev_msgs.h"
    "tt_metal/hw/inc/fabric_telemetry_msgs.h"
)
declare -a OUT_BASENAMES=(
    "dev_msgs"
    "fabric_telemetry"
)
declare -a INTERFACE_NAMESPACES=(
    "tt::tt_metal::dev_msgs"
    "tt::tt_fabric::fabric_telemetry"
)

mkdir -p "${OUT_DIR}"

for idx in "${!SRC_FILES[@]}"; do
    SRC_FILE=${SRC_FILES[$idx]}
    BASENAME=${OUT_BASENAMES[$idx]}
    INTF_NS=${INTERFACE_NAMESPACES[$idx]}
    OUT_INTF_FILE="${OUT_DIR}/${BASENAME}.hpp"
    OUT_IMPL_FILE="${OUT_DIR}/${BASENAME}_impl.hpp"

    cat > "${OUT_INTF_FILE}" <<EOF
// SPDX-FileCopyrightText: © ${YEAR} Tenstorrent AI ULC.
//
// SPDX-License-Identifier: Apache-2.0

// DO NOT EDIT THIS FILE!  It is generated from ${SRC_FILE}
// by ${SCRIPT}.
// This file provides arch- and core- independent accessors.
// You should use HAL to create a Factory object with programmable core
// as the argument (arch as implicit argument, handled by HAL), and then
// use the Factory to create views and/or memory-owning objects for
// different structs.
EOF

    cat > "${OUT_IMPL_FILE}" <<EOF
// SPDX-FileCopyrightText: © ${YEAR} Tenstorrent AI ULC.
//
// SPDX-License-Identifier: Apache-2.0

// DO NOT EDIT THIS FILE!  It is generated from ${SRC_FILE}
// by ${SCRIPT}.
// This file is to be embedded as part of arch-specifc code in HAL, wrapped in a namespace.
// It should not be used anywhere else.
EOF

    if ! $PYTHON "${SCRIPT_PY}" \
                 --append_mode \
                 --driver_ns="::tt::tt_metal::hal_structs" \
                 --driver_include_path="llrt/struct_view_driver.hpp" \
                 --interface_ns="${INTF_NS}" \
                 --raw_structs_ns="" \
                 "${SRC_ROOT}/${SRC_FILE}" "${OUT_INTF_FILE}" "${OUT_IMPL_FILE}"; then
        echo "Hint: did you modify ${SRC_FILE}?  Please note the comments at the top of the file."
        exit 1
    fi

    # some environment does not have a compatible clang-format, in which case we should
    # ignore the failure
    if clang-format -i "${OUT_INTF_FILE}" "${OUT_IMPL_FILE}" 2> /dev/null; then
        :
    fi
done
